import React from 'react';
import { Table, Input, Button, Popconfirm, Form, Select } from 'antd';

const EditableContext = React.createContext();

const EditableRow = ({ form, index, ...props }) => (
	<EditableContext.Provider value={form}>
		<tr {...props} />
	</EditableContext.Provider>
);

const EditableFormRow = Form.create()(EditableRow);

/**
 * 可编辑单元格
 */
class EditableCell extends React.Component {
	state = {
		editing: false
	};

	toggleEdit = () => {
		const editing = !this.state.editing;
		this.setState({ editing }, () => {
			if (editing) {
				this.input.focus();
			}
		});
	};

	save = e => {
		const { record, handleSave } = this.props;
		this.form.validateFields((error, values) => {
			if (error && error[e.currentTarget.id]) {
				return;
			}
			this.toggleEdit();
			handleSave({ ...record, ...values });
		});
	};

	renderCell = form => {
		this.form = form;
		const { children, dataIndex, record, title } = this.props;
		const { editing } = this.state;

		function renderForm(that, record, dataIndex) {
			if (record.editProps[dataIndex] === 'input') {
				return (
					<Input
						ref={node => (that.input = node)}
						onPressEnter={that.save}
						onBlur={that.save}
					/>
				);
			} else if (record.editProps[dataIndex] === 'select') {
				return (
					<Select
						ref={node => (that.input = node)}
						onPressEnter={that.save}
						onBlur={that.save}
					>
						{record.selectData.map((item, index) => {
							return (
								<Select.Option key={dataIndex + index}>{item}</Select.Option>
							);
						})}
					</Select>
				);
			}
		}
		return editing ? (
			<Form.Item style={{ margin: 0 }}>
				{form.getFieldDecorator(dataIndex, {
					rules: [
						{
							required: true,
							message: `${title} is required.`
						}
					],
					initialValue: record[dataIndex]
				})(renderForm(this, record, dataIndex))}
			</Form.Item>
		) : (
			<div
				className="editable-cell-value-wrap"
				style={{ paddingRight: 24 }}
				onClick={this.toggleEdit}
			>
				{children}
			</div>
		);
	};

	render() {
		const {
			editable,
			dataIndex,
			title,
			record,
			index,
			handleSave,
			children,
			...restProps
		} = this.props;
		return (
			<td {...restProps}>
				{editable ? (
					<EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
				) : (
					children
				)}
			</td>
		);
	}
}

class EditableTable extends React.Component {
	constructor(props) {
		super(props);
		this.columns = [
			{
				title: 'name',
				dataIndex: 'name',
				width: '30%',
				editable: true
			},
			{
				title: 'age',
				dataIndex: 'age'
			},
			{
				title: 'address',
				dataIndex: 'address'
			},
			{
				title: 'operation',
				dataIndex: 'operation',
				render: (text, record) =>
					this.state.dataSource.length >= 1 ? (
						<Popconfirm
							title="Sure to delete?"
							onConfirm={() => this.handleDelete(record.key)}
						>
							<a>Delete</a>
						</Popconfirm>
					) : null
			}
		];

		this.state = {
			dataSource: [
				{
					key: '0',
					name: 'Edward King 0',
					age: '32',
					address: 'London, Park Lane no. 0',
					editProps: {
						name: 'input',
						address: 'select'
					},
					selectData: [1, 2, 3, 4]
				},
				{
					key: '1',
					name: 'Edward King 1',
					age: '32',
					address: 'London, Park Lane no. 1',
					editProps: {
						age: 'input'
					}
				}
			],
			count: 2
		};
	}

	handleDelete = key => {
		const dataSource = [...this.state.dataSource];
		this.setState({
			dataSource: dataSource.filter(item => item.key !== key)
		});
	};

	handleAdd = () => {
		const { count, dataSource } = this.state;
		const newData = {
			key: count,
			name: `Edward King ${count}`,
			age: 32,
			address: `London, Park Lane no. ${count}`
		};
		this.setState({
			dataSource: [...dataSource, newData],
			count: count + 1
		});
	};

	handleSave = row => {
		const newData = [...this.state.dataSource];
		const index = newData.findIndex(item => row.key === item.key);
		const item = newData[index];
		newData.splice(index, 1, {
			...item,
			...row
		});
		this.setState({ dataSource: newData });
	};

	render() {
		const { dataSource } = this.state;
		let { form } = this.props;
		const components = {
			body: {
				row: EditableFormRow,
				cell: EditableCell
			}
		};
		function renderForm(that, record, dataIndex) {
			if (record.editProps[dataIndex] === 'input') {
				return (
					<Input
						ref={node => (that.input = node)}
						// onPressEnter={that.save}
						// onBlur={that.save}
					/>
				);
			} else if (record.editProps[dataIndex] === 'select') {
				return (
					<Select>
						{record.selectData.map((item, index) => {
							return (
								<Select.Option key={dataIndex + index}>{item}</Select.Option>
							);
						})}
					</Select>
				);
			}
		}

		const columns = this.columns.map(col => {
			// if (!col.editable) {
			// 	return col;
			// }
			return {
				...col,
				onCell: (record, rowIndex) => {
					return {
						record,
						// editable: col.editable,
						editable: record.editProps[col.dataIndex],
						dataIndex: col.dataIndex,
						title: col.title,
						handleSave: this.handleSave
					};
				}
			};
		});
		return (
			<div>
				<Button
					onClick={this.handleAdd}
					type="primary"
					style={{ marginBottom: 16 }}
				>
					Add a row
				</Button>
				<Table
					components={components}
					rowClassName={() => 'editable-row'}
					bordered
					dataSource={dataSource}
					columns={columns}
				/>
			</div>
		);
	}
}

export { EditableTable as default } ;
